package com.ly.juc;

import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;

/**
 * @Classname TestStampedLock
 * @Description TODO
 * @Date 2020/11/18 19:51
 * @Author 冷心影翼
 */
public class TestStampedLock {

	public static void main(String[] args) {
		TByReentrantLock();
		TByReentrantReadWriteLock();
		TByStampedLock();
	}

	public static void TByStampedLock() {
		StampedLock stampedLock = new StampedLock();
		HashMap<String,String> hashMap = new HashMap<>();


		Instant start  = Instant.now();
		for(int i=0;i<10;i++) {
			new Thread(() -> {
				long r = stampedLock.writeLock();
				try{
					for(int j=0;j<=1000;j++)
						hashMap.put(j+"",j+"");
				}catch(Exception e){
					e.printStackTrace();
				}finally {
					stampedLock.unlockWrite(r);
				}
			}).start();
		}

		for(int i=0;i<10000;i++) {
			new Thread(() -> {
				long l = stampedLock.tryOptimisticRead();

				if(!stampedLock.validate(l)) {
					l = stampedLock.readLock();
					try{
						for(int j=0;j<100_000;j++)
							hashMap.get(1+"");
					}catch(Exception e){

					}finally {
						stampedLock.unlockRead(l);
					}
				}

				hashMap.get(1+"");

			}).start();
		}

		while (Thread.activeCount() > 2) {

		}
		Instant end = Instant.now();
		System.out.println(Duration.between(start,end).toMillis());
		System.out.println(hashMap.get(1000+""));
	}

	public static void TByReentrantLock() {
		ReentrantLock reentrantLock = new ReentrantLock();
		HashMap<String,String> hashMap = new HashMap<>();


		Instant start  = Instant.now();
		for(int i=0;i<10;i++) {
			new Thread(() -> {
				reentrantLock.lock();
				try{
					for(int j=0;j<=1000;j++)
						hashMap.put(j+"",j+"");
				}catch(Exception e){
					e.printStackTrace();
				}finally {
					reentrantLock.unlock();
				}
			}).start();
		}

		for(int i=0;i<10000;i++) {
			new Thread(() -> {
				reentrantLock.lock();
				try{
					for(int j=0;j<100_000;j++)
						hashMap.get(1+"");
				}catch(Exception e){
					e.printStackTrace();
				}finally {
					reentrantLock.unlock();
				}
			}).start();
		}

		while (Thread.activeCount() > 2) {

		}
		Instant end = Instant.now();
		System.out.println(Duration.between(start,end).toMillis());
		System.out.println(hashMap.get(1000+""));
	}


	public static void TByReentrantReadWriteLock() {
		ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
		HashMap<String,String> hashMap = new HashMap<>();


		Instant start  = Instant.now();
		for(int i=0;i<10;i++) {
			new Thread(() -> {
				reentrantReadWriteLock.writeLock().lock();
				try{
					for(int j=0;j<=1000;j++)
						hashMap.put(j+"",j+"");
				}catch(Exception e){
					e.printStackTrace();
				}finally {
					reentrantReadWriteLock.writeLock().unlock();
				}
			}).start();
		}

		for(int i=0;i<10000;i++) {
			new Thread(() -> {
				reentrantReadWriteLock.readLock().lock();
				try{
					for(int j=0;j<100_000;j++)
						hashMap.get(1+"");
				}catch(Exception e){
					e.printStackTrace();
				}finally {
					reentrantReadWriteLock.readLock().unlock();
				}
			}).start();
		}

		while (Thread.activeCount() > 2) {

		}
		Instant end = Instant.now();
		System.out.println(Duration.between(start,end).toMillis());
		System.out.println(hashMap.get(1000+""));
	}

}
